package top.iszsq.utils;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import top.iszsq.base.entity.LoginRes;
import top.iszsq.base.entity.TokenInfo;
import top.iszsq.base.enums.RenderEnums;
import top.iszsq.base.exceptions.BizException;
import top.iszsq.system.entity.SysUser;

/**
 * 鉴权工具类
 * @author zsq
 * @date 2022/2/10 - 22:30
 */
@Component
public class AuthUtils {

    private static final Logger log = LoggerFactory.getLogger(AuthUtils.class);

    /**密码加密盐值**/
    @Value("${app.pwdSalt}")
    private String pwdSalt;

    /**
     * 账号密码hash
     * @param password
     * @return
     */
    public String encodePwd(String password){
        String pwdEncode = SaSecureUtil.md5BySalt(password, pwdSalt);
        return pwdEncode;
    }

    /**
     * 密码比对
     * @param password 原始密码
     * @param encodePwd 加密后密码字符
     * @return
     */
    public boolean comparingPwd(String password, String encodePwd){
        if (StringUtils.isBlank(password) || StringUtils.isBlank(encodePwd)) {
            return false;
        }
        // 对原密码再次加密
        String pwdEncode = SaSecureUtil.md5BySalt(password, pwdSalt);
        return encodePwd.equals(pwdEncode);
    }

    /**
     * 登录系统
     * @param sysUser 用户信息
     */
    public LoginRes login(SysUser sysUser){
        if (sysUser == null) {
            throw new BizException("用户信息不能为空");
        }
        if (StringUtils.isBlank(sysUser.getUid())) {
            throw new BizException("用户uid不能为空");
        }
        // sa登录，添加扩展参数至token
        StpUtil.login(sysUser.getUid(), SaLoginConfig
                .setExtra("id", sysUser.getId())
                .setExtra("uid", sysUser.getUid())
                .setExtra("avatar", sysUser.getAvatar())
                .setExtra("username", sysUser.getUsername())
                .setExtra("phone", sysUser.getPhone())
                .setExtra("nickname", sysUser.getNickname())
                .setExtra("state", sysUser.getState())
        );
        // sa-token信息
        SaTokenInfo saTokenInfo = StpUtil.getTokenInfo();

        // 本系统token信息
        TokenInfo tokenInfo = new TokenInfo();
        //  过期时间戳
        Long expiration = System.currentTimeMillis() + saTokenInfo.getTokenTimeout();
        tokenInfo.setExpiresIn(expiration);
        tokenInfo.setAccessToken(saTokenInfo.getTokenValue());

        // 登录成功返回内容
        LoginRes loginRes = new LoginRes();
        loginRes.setUserInfo(sysUser);
        loginRes.setTokenInfo(tokenInfo);

        return loginRes;
    }

    /**
     * 检查是否登录
     */
    public void checkLogin(){
        try {
            StpUtil.checkLogin();
        } catch (NotLoginException e) {
            throw new BizException(RenderEnums.needLogin);
        }
    }

    /**
     * 注销登录
     */
    public void logout(){
        // 当前会话注销登录
        StpUtil.logout();
    }

    /**
     * 当前用户信息
     */
    public SysUser currentUser(){
        try {
            SysUser sysUser = new SysUser();
            if (StpUtil.getExtra("id") != null) {
                sysUser.setId(Long.parseLong(StpUtil.getExtra("id").toString()));
            }
            if (StpUtil.getExtra("uid") != null) {
                sysUser.setUid(StpUtil.getExtra("uid").toString());
            }
            if (StpUtil.getExtra("username") != null) {
                sysUser.setUsername(StpUtil.getExtra("username").toString());
            }
            if (StpUtil.getExtra("avatar") != null) {
                sysUser.setAvatar(StpUtil.getExtra("avatar").toString());
            }
            if (StpUtil.getExtra("nickname") != null) {
                sysUser.setNickname(StpUtil.getExtra("nickname").toString());
            }
            if (StpUtil.getExtra("phone") != null) {
                sysUser.setPhone(StpUtil.getExtra("phone").toString());
            }
            if (StpUtil.getExtra("state") != null) {
                sysUser.setState(Integer.parseInt(StpUtil.getExtra("state").toString()));
            }

            return sysUser;
        } catch (NotLoginException e) {
            log.error(e.getMessage());
            throw new BizException(RenderEnums.needLogin);
        }
    }

}
